home *** CD-ROM | disk | FTP | other *** search
/ Hot Super Models / Hot Super Models.iso / unix / x11 / xv200.tar / xv-2.00 / xvxbm.c < prev   
C/C++ Source or Header  |  1992-01-02  |  6KB  |  238 lines

  1. /*
  2.  * xvxbm.c - load routine for X11 Bitmap format pictures
  3.  *
  4.  * LoadXBM(fname)  -  loads an X11 Bitmap file\
  5.  * WriteXBM(fp, pic, w, h)
  6.  */
  7.  
  8. /*
  9.  * Copyright 1989, 1990, 1991, 1992 by John Bradley and
  10.  *                       The University of Pennsylvania
  11.  *
  12.  * Permission to use, copy, and distribute for non-commercial purposes,
  13.  * is hereby granted without fee, providing that the above copyright
  14.  * notice appear in all copies and that both the copyright notice and this
  15.  * permission notice appear in supporting documentation.
  16.  *
  17.  * The software may be modified for your own purposes, but modified versions
  18.  * may not be distributed.
  19.  *
  20.  * This software is provided "as is" without any expressed or implied warranty.
  21.  *
  22.  * The author may be contacted via:
  23.  *    US Mail:   John Bradley
  24.  *               GRASP Lab, Room 301C
  25.  *               3401 Walnut St.
  26.  *               Philadelphia, PA  19104
  27.  *
  28.  *    Phone:     (215) 898-8813
  29.  *    EMail:     bradley@cis.upenn.edu
  30.  */
  31.  
  32.  
  33. #include "xv.h"
  34.  
  35.  
  36.  
  37. /*
  38.  * File Format:
  39.  *   (format identifier:  "#define" as first couple chars in file)
  40.  *
  41.  * looks for first line beginning with '#define'
  42.  *   reads "#define identifier width"  (identifier is ignored)
  43.  * looks for next line beginning with '#define'
  44.  *   reads "#define identifier height" (identifier is ignored)
  45.  * looks for next occurence of characters '0x'
  46.  *   read next two chars as two hex digits
  47.  *   move forward to next occurence of '0x'
  48.  *   repeat
  49.  */
  50.  
  51.  
  52. static int XBMError();
  53.  
  54.  
  55. /*******************************************/
  56. int LoadXBM(fname,nc)
  57.      char *fname;
  58.      int   nc;
  59. /*******************************************/
  60. {
  61.   FILE  *fp;
  62.   int    c, c1;
  63.   int    i, j, k, bit, w, h;
  64.   byte  *pix;
  65.   long   filesize;
  66.   char   line[256];
  67.   byte   hex[256];
  68.  
  69.   k = 0;
  70.  
  71.   fp=fopen(fname,"r");
  72.   if (!fp) return 1;
  73.  
  74.   /* figure out the file size (for Informational Purposes Only) */
  75.   fseek(fp, 0L, 2);
  76.   filesize = ftell(fp);
  77.   fseek(fp, 0L, 0);
  78.  
  79.  
  80.   /* read width:  skip lines until we hit a #define */
  81.   while (1) {
  82.     if (!fgets(line,256,fp)) 
  83.       return(XBMError("EOF reached in header info."));
  84.  
  85.     if (strncmp(line,"#define",7)==0) {
  86.       if (sscanf(line,"#define %*s %d", &w) != 1) 
  87.     return(XBMError("Unable to read 'width'"));
  88.       else break;
  89.     }
  90.   }
  91.  
  92.  
  93.   /* read height:  skip lines until we hit another #define */
  94.   while (1) {
  95.     if (!fgets(line,256,fp)) 
  96.       return(XBMError("EOF reached in header info."));
  97.  
  98.     if (strncmp(line,"#define",7)==0) {
  99.       if (sscanf(line,"#define %*s %d", &h) != 1) 
  100.     return(XBMError("Unable to read 'height'"));
  101.       else break;
  102.     }
  103.   }
  104.  
  105.  
  106.  
  107.   /* scan forward until we see the first '0x' */
  108.   c = getc(fp);  c1 = getc(fp);
  109.   while (c1!=EOF && !(c=='0' && c1=='x') ) { c = c1;  c1 = getc(fp); }
  110.  
  111.   if (c1==EOF) 
  112.     return(XBMError("No bitmap data found"));
  113.  
  114.  
  115.   /* load up the stuff XV expects us to load up */
  116.  
  117.   SetDirRButt(F_FORMAT, F_XBM);
  118.   SetDirRButt(F_COLORS, F_BWDITHER);
  119.  
  120.   SetISTR(ISTR_FORMAT,"X11 Bitmap  (%ld bytes)", filesize);
  121.   sprintf(formatStr, "%dx%d X11 Bitmap.",w,h);
  122.  
  123.   pic = (byte *) calloc(w*h,1);
  124.   if (!pic) FatalError("couldn't malloc 'pic'");
  125.  
  126.   pWIDE = w;  pHIGH = h;
  127.  
  128.   /* B/W bitmaps have a two entry colormap */
  129.   r[0] = g[0] = b[0] = 255;     /* 0 = white */
  130.   r[1] = g[1] = b[1] = 0;       /* 1 = black */
  131.  
  132.  
  133.   /* initialize the 'hex' array for zippy ASCII-hex -> int conversion */
  134.  
  135.   for (i=0; i<256; i++) hex[i]=0;
  136.   for (i='0'; i<='9'; i++) hex[i] = i - '0';
  137.   for (i='a'; i<='f'; i++) hex[i] = i + 10 - 'a';
  138.   for (i='A'; i<='F'; i++) hex[i] = i + 10 - 'A';
  139.  
  140.   /* read/convert the image data */
  141.  
  142.   for (i=0, pix=pic; i<h; i++)
  143.     for (j=0,bit=0; j<w; j++, pix++, bit = (++bit)&7) {
  144.  
  145.       if (!bit) {
  146.     /* get next byte from file.  we're already positioned at it */
  147.     c = getc(fp);  c1 = getc(fp);
  148.     if (c<0 || c1<0) { 
  149.       /* EOF: break out of loop */      
  150.       c=c1='0'; i=h; j=w;
  151.       XBMError("The file would appear to be truncated.");
  152.     }
  153.  
  154.     k = (hex[c] << 4) + hex[c1];
  155.  
  156.     /* advance to next '0x' */
  157.     c = getc(fp);  c1 = getc(fp);
  158.     while (c1!=EOF && !(c=='0' && c1=='x') ) { c = c1;  c1 = getc(fp); }
  159.       }
  160.  
  161.       *pix = (k&1) ? 1 : 0;
  162.       k = k >> 1;
  163.     }
  164.  
  165.   fclose(fp);
  166.  
  167.   return 0;
  168. }  
  169.  
  170.  
  171.  
  172. /*******************************************/
  173. static int XBMError(st)
  174. char *st;
  175. {
  176.   SetISTR(ISTR_WARNING,st);
  177.   return 1;
  178. }
  179.  
  180.  
  181. /*******************************************/
  182. int WriteXBM(fp, pic, w, h, fname)
  183. FILE *fp;
  184. byte *pic;
  185. int   w,h;
  186. char *fname;
  187. {
  188.   /* pic is expected to be an array of w*h bytes.  '0' is considered 'black'
  189.      non-zero is considered white.  Some sort of stippling algorithm should've
  190.      been called already to produce pic, otherwise the output won't be at all
  191.      useful */
  192.  
  193.   int   i,j,k,bit,len,nbytes;
  194.   byte *pix;
  195.   char name[256], *foo, *strchr();
  196.  
  197.   /* figure out a reasonable basename */
  198.   strcpy(name,fname);
  199.   foo = strchr(name,'.');
  200.   if (foo) *foo='\0';                 /* truncated name at first '.' */
  201.  
  202.   fprintf(fp,"#define %s_width %d\n",name,w);  
  203.   fprintf(fp,"#define %s_height %d\n",name,h);
  204.   fprintf(fp,"static char %s_bits[] = {\n",name);
  205.  
  206.   fprintf(fp," ");
  207.  
  208.   nbytes = h * ((w+7)/8);   /* # of bytes to write */
  209.  
  210.   for (i=0, len=1, pix=pic; i<h; i++) {
  211.     for (j=bit=k=0; j<w; j++,pix++) {
  212.       k = (k>>1);
  213.       if (*pix) k |= 0x80;
  214.       bit++;
  215.       if (bit==8) {
  216.     fprintf(fp,"0x%02x",(byte) ~k);
  217.     nbytes--;  len += 4;
  218.     if (nbytes) { fprintf(fp,",");  len++; }
  219.     if (len>72) { fprintf(fp,"\n ");  len=1; }
  220.     bit = k = 0;
  221.       }
  222.     }
  223.  
  224.     if (bit) {
  225.       k = k >> (8-bit);
  226.       fprintf(fp,"0x%02x",(byte) ~k);
  227.       nbytes--;  len += 4;
  228.       if (nbytes) { fprintf(fp,",");  len++; }
  229.       if (len>72) { fprintf(fp,"\n ");  len=1; }
  230.     }
  231.   }
  232.  
  233.   fprintf(fp,"};\n");
  234.  
  235.   if (ferror(fp)) return -1;
  236.   return 0;
  237. }
  238.